﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using Valentia.Kinection.Configuration;
using Valentia.Kinection.DataTypes;

namespace Valentia.Kinection.Configuration.Manager
{
    /// <summary>
    /// User control used to add/update service client
    /// </summary>
    public partial class DataUserControl : UserControl
    {
        #region Declarations

        /// <summary>
        /// Service client ID 
        /// </summary>
        private int dataUserID = -1;

        /// <summary>
        /// Service client login name
        /// </summary>
        private String dataUserLoginName = string.Empty;

        #endregion

        #region Constructor

        public DataUserControl()
        {
            InitializeComponent();

            this.clbJointIDs.Items.AddRange(Enum.GetNames(typeof(SkeletonJointID)));

            this.clbJointIDs.Items.Remove(SkeletonJointID.Count.ToString());
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Set the form control values with the provided Service client info
        /// </summary>
        /// <param name="dataUser">Service client</param>
        public void InitializeWithDataUserData(DataUser dataUser)
        {
            this.dataUserID = dataUser.ID;
            this.dataUserLoginName = dataUser.Login;

            txtClientName.Text = dataUser.Name;
            txtLoginName.Text = dataUser.Login;
            txtPassword.Text = dataUser.Password;
            chkActive.Checked = dataUser.Active;
            chkVideoStream.Checked = dataUser.SendVideoFrame;
            chkDepthStream.Checked = dataUser.SendDepthFrame;            
            chkSkeletonStream.Checked = dataUser.SendSkeletonFrame;

            txtClientName.ReadOnly = true;
            txtLoginName.ReadOnly = true;
            
            List<DataUserAllowedSkeletonJoint> dataUserAllowedSkeletonJoints =
               ConfigurationHelper.GetDataUserAllowedSkeletonJointsByDataUserID(dataUser.ID);

            foreach (DataUserAllowedSkeletonJoint skeletonJointInfo in dataUserAllowedSkeletonJoints)
            {
                this.clbJointIDs.SetItemChecked(this.clbJointIDs.Items.IndexOf(skeletonJointInfo.SkeletonJointIDEnm.ToString()), true);
            }

            btnSaveUpdate.Text = "   Update";            
        }

        #endregion

        #region Private Methods
        
        /// <summary>
        /// Validates the service client data to be saved
        /// </summary>
        /// <returns>True/False : service client data is valid</returns>
        private bool IsValidData()
        {
            errProvider.Clear();
            if (txtClientName.Text.Trim().Equals(string.Empty))
            {
                errProvider.SetError(txtClientName, "Please provide client name");
                txtClientName.Focus();
                return false;
            }

            if (!Regex.Match(txtClientName.Text, "^[a-zA-Z0-9 ]+$").Success)
            {
                errProvider.SetError(txtClientName, "Client name must be alphanumeric");
                txtClientName.Focus();
                return false;
            }

            if (txtLoginName.Text.Trim().Length == 0)
            {
                errProvider.SetError(txtLoginName, "Please provide login name");
                txtLoginName.Focus();
                return false;
            }

            if (!Regex.Match(txtLoginName.Text, "^[a-zA-Z0-9 ]+$").Success)
            {
                errProvider.SetError(txtLoginName, "Login name must be alphanumeric");
                txtLoginName.Focus();
                return false;
            }

            if (txtPassword.Text.Trim().Length == 0)
            {
                errProvider.SetError(txtPassword, "Please provide password");
                txtPassword.Focus();
                return false;
            }

            if (txtPassword.Text.IndexOf(" ", 0) != -1)
            {
                errProvider.SetError(txtPassword, "Space is not allowed in password");
                txtPassword.Focus();
                return false;
            }

            return true;
        }

        #endregion

        #region Form control events

        /// <summary>
        /// Occurs when Save/Update button is clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnSaveUpdate_Click(object sender, EventArgs e)
        {
            if (IsValidData())
            {
                if (this.dataUserLoginName.Equals(string.Empty))
                {
                    if (ConfigurationHelper.GetDataUserByLoginName(txtLoginName.Text.Trim()) !=  null)
                    {
                        errProvider.SetError(txtLoginName, "Login name already exists");
                        txtLoginName.Focus();
                        return;
                    }

                    dataUserID = ConfigurationHelper.SaveDataUser(txtClientName.Text.Trim()
                        , txtLoginName.Text.Trim(), txtPassword.Text, chkActive.Checked
                        , chkVideoStream.Checked, chkDepthStream.Checked, chkSkeletonStream.Checked).ID;
                }
                else
                {
                    using (ConfigDatabaseEntities context = ConfigurationHelper.GetContext())
                    {
                        DataUser dataUser = ConfigurationHelper.GetDataUserByLoginName(context, this.dataUserLoginName);

                        if (dataUser != null)
                        {
                            dataUser.Name = txtClientName.Text.Trim();
                            dataUser.Login = txtLoginName.Text.Trim();
                            dataUser.Password = txtPassword.Text;
                            dataUser.Active = chkActive.Checked;
                            dataUser.SendVideoFrame = chkVideoStream.Checked;
                            dataUser.SendDepthFrame = chkDepthStream.Checked;
                            dataUser.SendSkeletonFrame = chkSkeletonStream.Checked;

                            context.SaveChanges();
                        }
                    }

                    ConfigurationHelper.DeleteDataUserAllowedSkeletonJointsByDataUserID(this.dataUserID);
                }

                foreach (object itemChecked in clbJointIDs.CheckedItems)
                {
                    ConfigurationHelper.SaveDataUserAllowedSkeletonJoint(this.dataUserID
                        , (int)(SkeletonJointID)(Enum.Parse(typeof(SkeletonJointID), itemChecked.ToString(), true)));
                }

                ((Form)(this.Parent)).Close();
            }
        }

        /// <summary>
        /// Occurs when Cancel button is clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            ((Form)(this.Parent)).Close();
        }

        /// <summary>
        /// Occurs when select all check box checked status change
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void chkSelectAll_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSelectAll.Checked)
            {
                for (int i = 0; i < clbJointIDs.Items.Count; i++)
                {
                    clbJointIDs.SetItemChecked(i, true);
                }
            }
            else
            {
                for (int i = 0; i < clbJointIDs.Items.Count; i++)
                {
                    clbJointIDs.SetItemChecked(i, false);
                }
            }
        }

        #endregion


    }
}
